package com.github.icloudpay.pay.core.service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.github.icloudpay.pay.core.biz.PayOrderBiz;
import com.github.icloudpay.pay.core.biz.PaySerialBiz;
import com.github.icloudpay.pay.core.entity.PayOrder;
import com.github.icloudpay.pay.core.entity.PaySerial;
import com.github.icloudpay.pay.core.feign.PayChannelConfigFeign;
import com.github.icloudpay.pay.core.service.pay.PayCallbackService;
import com.github.icloudpay.pay.core.service.pay.alipay.util.AlipayNotify;
import com.github.icloudpay.pay.core.service.refund.RefundCallbackService;
import com.github.wxiaoqi.security.common.admin.pay.request.CallbackRequest;

/**
 * 支付宝回调
 * @author hexufeng
 *
 */
@Service("aliPayCallBackService")
public class AliPayCallBackService {
	
	private static final Logger logger = (Logger) LoggerFactory.getLogger(AliPayCallBackService.class);
	
	@Autowired
	private PayCallbackService payCallbackService;
	@Autowired
	private PaySerialBiz paySerialBiz;
	@Autowired
	private PayOrderBiz payOrderBiz;
	@Autowired
	private PayChannelConfigFeign payChannelConfigFeign;
	@Autowired
	private RefundCallbackService refundCallbackService;
	
	public String callBack(Map<String, Object> request){
		
		Map<String, Object> requestParams = new HashMap<String, Object>();
        requestParams.putAll(request);
        requestParams.remove("TransCode");
        requestParams.remove("$sessionClass");
        requestParams.remove("serviceCode");
        logger.info("支付宝回调开始 ： requestParams is{}",requestParams);
        
        Map<String, String> params = new HashMap<String, String>();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            Object objValue = requestParams.get(name);
            if(objValue instanceof List){
                @SuppressWarnings("unchecked")
                List<String> values = ( List<String>)objValue;
                String valueStr = "";
                for (int i = 0; i < values.size(); i++) {
                    valueStr = (i == values.size() - 1) ? valueStr + values.get(i) : valueStr + values.get(i) + ",";
                }
                params.put(name, valueStr);
            }else{
                params.put(name,(String)objValue);
            }
        }
		
        logger.info("支付宝回调解析参数 ： params is{}",params);
        
        // 获取支付宝的通知返回参数
        // 商户订单号
        String out_trade_no = requestParams.get("out_trade_no").toString();
        // 支付宝交易号
        String trade_no = requestParams.get("trade_no").toString();
        // 交易状态
        String trade_status = requestParams.get("trade_status").toString();
        // 交易金额
        String total_amount = requestParams.get("total_amount").toString();
        //退款金额
        String refund_fee = requestParams.get("refund_fee").toString();

        CallbackRequest callbackRequest = new CallbackRequest();
        callbackRequest.setRequestNo(out_trade_no);
        callbackRequest.setOrderAmt(new BigDecimal(total_amount));
        callbackRequest.setRemoteTxJournalNo(trade_no);
        
        //app支付采用支付宝公钥验签
        Map<String, Object> configMap = getAlipayConfigDecorator(out_trade_no);
        if(configMap == null){
            return "fail";
        }
        if (AlipayNotify.verify(params,configMap)) {
            
            logger.info("支付宝回调验签成功trade_no:{},out_trade_no:{},trade_status:{}",trade_no,out_trade_no,trade_status);
            
            if(StringUtils.isEmpty(refund_fee)){
            	//为空是支付回调
            	// 验证成功
                if (trade_status.equals("TRADE_SUCCESS")) {
                    // 支付完成
                    callbackRequest.setStatus("00");
                    payCallbackService.callBack(callbackRequest);
                    return "success";
                }else {
                    logger.info("支付宝回调状态{},不做处理.",trade_status);
                    callbackRequest.setStatus("01");
                    payCallbackService.callBack(callbackRequest);
                    return "success";
                }
            }else{
            	//不为空是退款回调
            	// 验证成功
                if (trade_status.equals("TRADE_CLOSED")) {
                    // 支付完成
                    callbackRequest.setStatus("00");
                    refundCallbackService.callBack(callbackRequest);
                    return "success";
                }else {
                    logger.info("支付宝回调状态{},不做处理.",trade_status);
                    callbackRequest.setStatus("01");
                    refundCallbackService.callBack(callbackRequest);
                    return "success";
                }
            }
        } else {
            // 验证失败
            logger.error("验证签名失败params is :{}",params);
            return "fail";
        }
	}
	
	private Map<String, Object> getAlipayConfigDecorator(String out_trade_no){
		PaySerial paySerial = new PaySerial();
		paySerial.setSerialNo(out_trade_no);
		PaySerial selectPaySerial = paySerialBiz.selectOne(paySerial);
        if(selectPaySerial == null){
            logger.error("查询支付订单为空,out_trade_no:{}",out_trade_no);
            return null;
        }
        PayOrder payOrder = new PayOrder();
		payOrder.setPayOrderNo(selectPaySerial.getPayOrderNo());
		payOrder.setPlatformId(selectPaySerial.getPlatformId());
		PayOrder selectPayOrder = payOrderBiz.selectOne(payOrder);
		Map<String, Object> reqMap = new HashMap<String, Object>();
    	reqMap.put("platformId", selectPayOrder.getPlatformId());
    	reqMap.put("merchantId", selectPayOrder.getMerchantId());
    	reqMap.put("payChannelNo", selectPaySerial.getPayChannelNo());
		Map<String, Object> respMap = payChannelConfigFeign.query(reqMap);
		@SuppressWarnings("unchecked")
		Map<String, Object> configMap = (Map<String, Object>)respMap.get("payChannelConfigInfo");
        return configMap;
    }
}
